// -*- c-basic-offset: 2 default-tab-width: 2 indent-tabs-mode: t -*-
// vim: autoindent tabstop=2 noexpandtab shiftwidth=2 softtabstop=2
//===------------ RPrinter.cpp
//
//             This file is part of the reactor project
//                Author: R-Core Team
//
//===---------------------------------------------------------------------===//

#include "Array.h"
#include "Closure.h"
#include "Promise.h"
#include "Const.h"
#include "RModule.h"
#include "Bindings.h"

using namespace R;

void Vector::print() {
	asSelf(Vector);

	printf("Vector@%p %.3d:", self, self->length);
	for (int i = 0; i < self->length; i++) {
		if(self->content[i]) {
			printf("\n\t");
			self->content[i]->print();
		} else {
			printf("\n\t"); // FIXME remove me when NULL will be a proper type
			Any::printNull();
		}
	}
}

void Any::printNull(){ // FIXME remove me when NULL will be a proper type
			printf("NULL");
}

void String::print() {
	asSelf(String);
  printf("String@%p %.3d: [ ", self , self->length);
  for(unsigned i = 0; i < self->length; i++)
  	if(self->content[i] == getNA<String>())
  		printf("NA\t");
  	else
  		printf("\"%s\"\t", self->content[i]);
  printf("]");
}

void Logical::print() {
	asSelf(Logical);
  printf("Logical@%p %.3d: [ ", self , self->length);
  for(unsigned i = 0; i < self->length; i++)
  	if(self->content[i] == getNA<Logical>())
  		printf("NA ");
  	else
  		printf("%2s ", convert<unsigned, char*>(self->content[i]));
  printf("]");
}

void Closure::print() {
	asSelf(Closure);
  printf("Closure@%p[%s::%x] <", self, self->fun->module->fileName, self->fun->id);
	self->env->print();
	printf(">");
}

void Bindings::print() {
	asSelf(Bindings);
	R_VAR(Symbol*, sym);
	R_VAR(Any*,    val);
	
  for(int i = 0; i < self->size; i++) {
		printf("    binding[%d]: ", i);
		sym = self->key(i); sym->print();
		printf(" -> ");
		val = self->get(i); val->print();
		printf("\n");
  }
}

void RModule::print() {
	printf("Module<%s>", fileName);
}

void FunInfo::print(){
	printf("%s<%s::%d>: 0x%x to 0x%x\t closures: %d\t JIT: %p\t code: %p", (this->isClosure()) ? "function" : "promise",
			module->fileName,
			id,
			start,
			end,
			hasClosure,
			jitFun,
			code);
}

void Environment::print() {
	asSelf(Environment);

  printf("Environment@%p", self);
}

void CollectableEnvironment::inspect() {
	asSelf(CollectableEnvironment);
	R_VAR(Symbol*, sym);
	R_VAR(Any*,    val);

//	Assert(!envIdx);
	print();
	printf(": ");
	if(self->fun) {
		self->fun->print();
		printf("\n");
		for(int i = 0; i < self->length(); i++) {
			printf("[%.2d] %s: ", i, self->fun->writeSet.get(i)->text);
			val = self->content[i];
			if(val) {
				val->print();
				printf("\n");
			} else
				printf("MISSING\n");
		}
	} else
		printf("\n");
	if(self->bindings) {
		printf("Extension:\n");
		self->bindings->print();
	}
	printf("\n");

	if(enclosing)
		enclosing->inspect();
}

void Int::print() {
	asSelf(Int);
  printf("Int@%p %.3d: [ ", self , self->length);
  for(unsigned i = 0; i < self->length; i++)
  	if(self->content[i] == getNA<Int>())
  		printf("NA ");
  	else
  		printf("%d ", self->content[i]);
  printf("]");
}

void Double::print() {
	asSelf(Double);
  printf("Double@%p %.3d: [ ", self , self->length);
  for(unsigned i = 0; i < self->length; i++)
  	if(self->content[i] == getNA<Double>())
  		printf("NA ");
  	else
  		printf("%g ", self->content[i]);
  printf("]");
}

void Promise::print() {
	asSelf(Promise);
  printf("Promise@%p<%.4x,%p,", self, self->fun->id, self->envInfo);
	if(self->value) {
		self->value->print();
		printf(">");
	} else printf("Unbound>");
}

void Symbol::print() {
	asSelf(Symbol);
	printf("Symbol@%p: %s", self, self->text);
}
